package com.epam.player.vkapi.music;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.jsoup.Connection;
import org.jsoup.nodes.Document;

import com.epam.player.vkapi.ApllicationContext;
import com.epam.player.vkapi.common.APIConstant;
import com.epam.player.vkapi.exceptions.TemporarilyUnavailableServiceException;
import com.epam.player.vkapi.model.ApplContextTypes;
import com.epam.player.vkapi.model.Song;

public class MusicManager {

	private static final Logger LOG = Logger.getLogger(MusicManager.class);

	private Connection connection;
	private ParserRequest parserRequest;

	public MusicManager() {
		parserRequest = new ParserRequest();
		LOG.info("Get " + ApplContextTypes.CONNECTION
				+ " from ApllicationContext");
		connection = (Connection) ApllicationContext
				.getFromContext(ApplContextTypes.CONNECTION);
	}

	public List<Song> getPopularSongs(int offset)
			throws TemporarilyUnavailableServiceException {
		String url = "http://vk.com/audio?act=get_popular&al=1&offset=";
		Document document = null;
		if (offset > 0) {
			while ((offset % 100 != 0) && (offset % 50 != 0)) {
				offset++;
			}
		}
		try {
			LOG.info("Get popular songs " + url + offset);
			document = connection.url(url + offset).timeout(10000).get();
		} catch (IOException e) {
			LOG.error(e);
			throw new TemporarilyUnavailableServiceException(e);
		}
		List<Song> songs = null;
		try {
			songs = parserRequest.parseSongs(document);
		} catch (MalformedURLException e) {
			LOG.error(e);
		}
		LOG.info("Size of list is " + songs.size());
		return songs;
	}

	public List<Song> searchSongs(String filter, int offset)
			throws TemporarilyUnavailableServiceException {
		String query = "http://vk.com/search?al=1&c%5Bq%5D=";
		try {
			query = query + URLEncoder.encode(filter, "UTF-8");
		} catch (UnsupportedEncodingException e1) {
			LOG.error("Can't encode 'filter'", e1);
		}
		if (offset == 0) {
			query = query + "&c%5Bsection%5D=audio";
		} else {
			while (offset % 100 != 0) {
				offset++;
			}
			query = query + "&c%5Bsection%5D=audio&offset=" + offset;
		}
		LOG.info("Search music " + query);
		Document document2 = null;
		try {
			document2 = connection.url(query).timeout(10000).post();
		} catch (SocketTimeoutException e) {
			LOG.error(e);
			throw new TemporarilyUnavailableServiceException(e);
		} catch (IOException e) {
			LOG.error(e);
		}
		List<Song> songs = null;
		try {
			songs = parserRequest.parseSearchResult(document2);
		} catch (MalformedURLException e) {
			LOG.error(e);
		}
		LOG.info("Size of list is " + songs.size());
		return songs;
	}

	public List<Song> getMyList() throws TemporarilyUnavailableServiceException {
		String query = "http://vk.com/audio?act=load_audios_silent&al=1&edit=0&gid=0";
		LOG.info("Get my list " + query);
		Document document2 = null;
		try {
			document2 = connection.url(query).timeout(10000).post();
		} catch (IOException e) {
			LOG.error(e);
			throw new TemporarilyUnavailableServiceException(e);
		}
		List<Song> songs = null;
		try {
			songs = parserRequest.parseSongs(document2);
		} catch (MalformedURLException e) {
			LOG.error(e);
		}
		LOG.info("Size of list is " + songs.size());
		return songs;

	}

	@SuppressWarnings("unchecked")
	public boolean addToMyListSongs(Song song)
			throws TemporarilyUnavailableServiceException {
		boolean result = false;
		LOG.info("Add " + song + " to My Music");
		LOG.info("Get user's hash from " + ApplContextTypes.DATA);
		Map<String, String> data = (Map<String, String>) ApllicationContext
				.getFromContext(ApplContextTypes.DATA);
		String hash = data.get(APIConstant.HASH_AUDIO_USER);
		LOG.info("Hash is  " + hash);
		StringBuilder builder = new StringBuilder();
		String query = "http://vk.com/audio?act=add&aid=";
		builder.append(query);
		builder.append(song.getAid());
		builder.append("&al=1&hash=");
		builder.append(hash);
		builder.append("&oid=");
		builder.append(song.getOid());
		query = builder.toString();
		LOG.info("Add song " + query);
		Document document2 = null;
		try {
			document2 = connection.url(query).timeout(10000).post();
		} catch (IOException e) {
			result = false;
			LOG.error(e);
			throw new TemporarilyUnavailableServiceException(e);
		}
		if (document2.toString().indexOf("Access denied") != -1) {
			LOG.error("Access denied for add " + song);
			result = false;
		}
		LOG.info("Added " + song + " to My Music");
		return result;
	}
}
